const chalk = require('chalk');
const shell = require('shelljs');
const util = require('util');
exports.exec = util.promisify(shell.exec);
exports.execSync = util.promisify(require('child_process').execSync);
exports.execa = require('execa')
// exports.exec = require('child_process').promises.exec;

exports.shell = shell
// execute a single shell command where "cmd" is a string
exports.exec2 = function (cmd, cb) {
    // this would be way easier on a shell/bash script :P
    var child_process = require('child_process');
    var parts = cmd.split(/\s+/g);
    var p = child_process.spawn(parts[0], parts.slice(1), { stdio: 'inherit' });
    p.on('exit', function (code) {
        var err = null;
        if (code) {
            err = new Error('command "' + cmd + '" exited with wrong status code "' + code + '"');
            err.code = code;
            err.cmd = cmd;
        }
        if (cb) cb(err);
    });
};


// execute multiple commands in this.
// this could be replaced by any flow control lib
function series(cmds, cb = () => void 0) {
    var execNext = function () {
        let cmd = cmds.shift()
        let options = {}
        const isObject = Object.prototype.toString.call(cmd) === '[object Object]'
        if (isObject) {
            let { cmd: val, ...rest } = cmd
            cmd = val
            options = rest
        }
        console.log(chalk.blue('run command: ') + chalk.magenta(cmd));
        shell.exec(cmd, options, function (err) {
            if (err) {
                cb(err);
            } else {
                if (cmds.length) execNext();
                else cb(null);
            }
        });
    };
    execNext();
};

exports.seriesa = function seriesa(cmds) {
    return new Promise((resolve, reject) => {
        function cb(err) {
            err ? reject() : resolve()
        }
        series(cmds, cb)
    })
}

exports.series = series